import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { DataSource } from 'typeorm';
import { FanqieCrawler } from './fanqie-crawler.service';
import { QidianCrawlerV5 } from './qidian-crawler-v5.service';
import { NovelTaskService } from './novel-task.service';
import { CategoryMappingService } from './category-mapping.service';
import { NovelInfo } from '../interfaces/crawler.interface';
import { Novel } from '../entities/novel.entity';
import { NovelChapter } from '../entities/novel-chapter.entity';
import { MasterCategory } from '../entities/master-category.entity';

export interface CrawlResult {
  success: boolean;
  data?: any;
  error?: string;
}

export interface NovelCrawlData {
  title: string;
  author: string;
  cover?: string;
  category?: string;
  tags?: string[];
  description?: string;
  chapters?: number;
  status?: string;
  wordCount?: string;
  updateTime?: string;
  platform: string;
  platformName: string;
  originalUrl: string;
  chapterList?: Array<{
    title: string;
    url?: string;
    index: number;
    isFree?: boolean;
    content?: string;
    volumeName?: string;
  }>;
  // 新增字段，用于跟踪异步任务状态
  parseTaskId?: string | null;
  isContentParsed?: boolean;
}

@Injectable()
export class NovelCrawlerService {
  private readonly logger = new Logger(NovelCrawlerService.name);
  private readonly fanqieCrawler: FanqieCrawler;
  private readonly qidianCrawler: QidianCrawlerV5;

  constructor(
    private configService: ConfigService,
    private dataSource: DataSource,
    private novelTaskService: NovelTaskService,
    private categoryMappingService: CategoryMappingService,
  ) {
    this.fanqieCrawler = new FanqieCrawler();
    this.qidianCrawler = new QidianCrawlerV5(
      dataSource.getRepository(Novel),
      dataSource.getRepository(NovelChapter),
      dataSource.getRepository(MasterCategory),
      dataSource,
      this.categoryMappingService,
    );
  }

  async parseNovelUrl(url: string): Promise<CrawlResult> {
    try {
      this.logger.log(`开始解析小说链接: ${url}`);

      const platform = this.detectPlatform(url);
      if (!platform) {
        return {
          success: false,
          error: '不支持的链接格式',
        };
      }

      let crawlData: NovelCrawlData;

      switch (platform) {
        case 'fanqie':
          crawlData = await this.parseFanqie(url);
          break;
        case 'changdunovel':
          // changdunovel.com 也使用番茄小说的解析器
          crawlData = await this.parseFanqie(url);
          break;
        case 'qidian':
          crawlData = await this.parseQidian(url);
          break;
        default:
          return {
            success: false,
            error: '暂不支持该平台',
          };
      }

      return {
        success: true,
        data: crawlData,
      };
    } catch (error) {
      this.logger.error(`解析小说链接失败: ${error.message}`, error.stack);
      return {
        success: false,
        error: '解析失败，请检查链接是否正确',
      };
    }
  }

  public detectPlatform(url: string): string | null {
    const platforms = {
      'changdunovel.com': 'changdunovel', // 畅读小说，使用番茄解析器
      'fanqienovel.com': 'fanqie',
      'novel.toutiao.com': 'fanqie',
      'qidian.com': 'qidian',
      'jjwxc.net': 'jjwxc',
      'zongheng.com': 'zongheng',
    };

    for (const [domain, platform] of Object.entries(platforms)) {
      if (url.includes(domain)) {
        return platform;
      }
    }
    return null;
  }

  private async parseFanqie(url: string): Promise<NovelCrawlData> {
    try {
      this.logger.log(`开始解析番茄小说链接: ${url}`);

      // 如果是分享链接，先获取真实页面URL
      let realUrl = url;
      if (url.includes('changdunovel.com') || url.includes('share')) {
        realUrl = await this.fanqieCrawler.parseShareUrl(url);
        this.logger.log(`分享链接解析完成，真实URL: ${realUrl}`);
      }

      const novelInfo: NovelInfo =
        await this.fanqieCrawler.getNovelInfo(realUrl);

      this.logger.log(
        `番茄小说解析结果: 标题="${novelInfo.title}", 作者="${novelInfo.author}"`,
      );

      return {
        title: novelInfo.title,
        author: novelInfo.author,
        cover: novelInfo.cover,
        category: novelInfo.category || '其他',
        tags: ['小说'], // 可以根据category转换为标签
        description: novelInfo.description,
        chapters: novelInfo.chapterList.length,
        status: novelInfo.status === 1 ? '已完结' : '连载中',
        wordCount: novelInfo.wordCount,
        platform: 'fanqie',
        platformName: '番茄小说',
        originalUrl: url,
        chapterList: novelInfo.chapterList.slice(0, 50), // 限制章节数量
      };
    } catch (error) {
      this.logger.error(`解析番茄小说失败: ${error.message}`, error.stack);
      throw new Error('解析番茄小说失败');
    }
  }

  private parseChangdunovel(url: string): Promise<NovelCrawlData> {
    // changdunovel 实际上使用番茄小说的解析器
    return this.parseFanqie(url);
  }

  private async parseQidian(url: string): Promise<NovelCrawlData> {
    try {
      this.logger.log(`开始解析起点小说链接: ${url}`);

      // 使用新的混合模式：先快速解析基础信息（同步），再异步处理章节内容
      const basicResult = await this.qidianCrawler.parseBasicInfoOnly(url);

      this.logger.log(
        `起点小说基础信息解析完成: 标题="${basicResult.title}", 作者="${basicResult.author}", 章节数=${basicResult.chapters.length}`,
      );

      // 创建章节内容异步处理任务
      const task = await this.novelTaskService.createChapterContentTask(
        basicResult.id,
        url,
        basicResult.title,
        'qidian',
      );

      return {
        title: basicResult.title,
        author: basicResult.author,
        cover: basicResult.coverImage,
        category: basicResult.category || '其他',
        tags: basicResult.tags || ['起点'],
        description: basicResult.description,
        chapters: basicResult.chapters.length,
        status: basicResult.status,
        wordCount: basicResult.wordCount,
        updateTime: basicResult.updateTime,
        platform: 'qidian',
        platformName: '起点中文网',
        originalUrl: url,
        chapterList: basicResult.chapters.map((chapter: any) => ({
          title: chapter.title,
          url: '', // 不返回URL给前端
          index: chapter.chapterNumber,
          isFree: chapter.isFree === 1,
          content: '', // 内容将异步获取
          volumeName: chapter.volumeName || '正文',
        })),
        // 新增字段，用于跟踪异步任务状态
        parseTaskId: task.taskId,
        isContentParsed: false, // 章节内容是否已解析
      };
    } catch (error) {
      this.logger.error(`解析起点小说失败: ${error.message}`, error.stack);
      throw new Error('解析起点小说失败');
    }
  }

  private parseJjwxc(url: string): Promise<NovelCrawlData> {
    // TODO: 实现晋江文学城解析
    throw new Error('晋江文学城解析功能待实现');
  }

  private parseZongheng(url: string): Promise<NovelCrawlData> {
    // TODO: 实现纵横中文网解析
    throw new Error('纵横中文网解析功能待实现');
  }
}
